#include "qipan.h"
#include <QPainter>
#include <QDebug>
#include <QMessageBox>
#include <QLinearGradient>
#include <QRandomGenerator>

QiPan::QiPan(QWidget *parent)
    : QWidget(parent),
      m_gameState(PLAYING),
      m_winner(EMPTY),
      m_currentPlayer(PLAYER),
      m_playerRole(PLAYER),
      m_hoverX(-1),
      m_hoverY(-1),
      m_hoverFlag(false),
      m_aiLevel(2),
      m_verificationState(VERIFIED),
      m_expectedRole(EMPTY),
      m_marginLeft(0),
      m_marginTop(0),
      m_gameFlowState(PLAYER_TURN)
{
    setMinimumSize(500, 500);
    m_aiTimer.setSingleShot(true);
    connect(&m_aiTimer, &QTimer::timeout, this, &QiPan::computerMove);
    m_verificationTimer.setInterval(500);
    connect(&m_verificationTimer, &QTimer::timeout, this, &QiPan::checkVerification);
    resetGame();
    setMouseTracking(true);
}

void QiPan::triggerComputerMove() {
    if (m_gameFlowState == COMPUTER_TURN) {
        computerMove();
    }
}

void QiPan::checkVerification()
{
    emit requestVerification(m_verifyX, m_verifyY, m_expectedRole);
}


void QiPan::resizeEvent(QResizeEvent *event) {
    Q_UNUSED(event);
    int minDimension = qMin(width(), height());
    m_cellSize = (minDimension - 40) / BOARD_SIZE;
    int boardTotalSize = m_cellSize * BOARD_SIZE;
    m_marginLeft = (width() - boardTotalSize) / 2;
    m_marginTop = (height() - boardTotalSize) / 2;
    update();
}

void QiPan::resetGame() {
    qDebug() << "重置游戏 - 当前玩家:"
            << (m_currentPlayer == PLAYER ? "玩家" : "电脑")
            << "游戏状态:"
            << (m_gameFlowState == PLAYER_TURN ? "玩家回合" : "电脑回合");
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            m_chessboard[x][y] = EMPTY;
        }
    }
    
    m_gameState = PLAYING;
    m_winner = EMPTY;
    m_currentPlayer = (m_playerRole == PLAYER) ? PLAYER : COMPUTER;
    m_moveHistory.clear();
    m_moveRoles.clear();
    m_hoverX = -1;
    m_hoverY = -1;
    m_hoverFlag = false;
    m_gameFlowState = (m_currentPlayer == PLAYER) ? PLAYER_TURN : COMPUTER_TURN;
    if (m_currentPlayer == COMPUTER) {
        m_aiTimer.start(500);
    }

    if (m_playerRole == PLAYER) {
        m_currentPlayer = PLAYER;
        m_gameFlowState = PLAYER_TURN;
    } else {
        m_currentPlayer = COMPUTER;
        m_gameFlowState = COMPUTER_TURN;
    }

    update();
    emit gameStatusChanged();
}

void QiPan::setPlayerRole(ROLE role) {
    m_playerRole = role;
    // 确保切换角色后状态机同步更新
    m_currentPlayer = (m_playerRole == PLAYER) ? PLAYER : COMPUTER;
    m_gameFlowState = (m_currentPlayer == PLAYER) ? PLAYER_TURN : COMPUTER_TURN;
    resetGame();
}

void QiPan::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    QLinearGradient bgGradient(0, 0, width(), height());
    bgGradient.setColorAt(0, QColor(240, 240, 240));
    bgGradient.setColorAt(1, QColor(200, 200, 200));
    painter.fillRect(rect(), bgGradient);

    drawBoard(painter);
    drawPieces(painter);

    if (m_gameState == PLAYING && m_hoverFlag &&
        m_hoverX >= 0 && m_hoverY >= 0 &&
        m_chessboard[m_hoverX][m_hoverY] == EMPTY) {
        drawHover(painter);
    }



    if (m_verificationState == VERIFYING) {
        int centerX = m_marginLeft + m_verifyX * m_cellSize + m_cellSize / 2;
        int centerY = m_marginTop + m_verifyY * m_cellSize + m_cellSize / 2;
        painter.setPen(QPen(Qt::yellow, 3));
        painter.drawEllipse(QPoint(centerX, centerY), m_cellSize / 3, m_cellSize / 3);
        painter.setPen(Qt::black);
        painter.drawText(rect(), Qt::AlignCenter, "验证中...");
    }
    else if (m_verificationState == FAILED) {
        int centerX = m_marginLeft + m_verifyX * m_cellSize + m_cellSize / 2;
        int centerY = m_marginTop + m_verifyY * m_cellSize + m_cellSize / 2;
        painter.setPen(QPen(Qt::red, 3));
        painter.drawEllipse(QPoint(centerX, centerY), m_cellSize / 3, m_cellSize / 3);
        painter.setPen(Qt::red);
        painter.drawText(rect(), Qt::AlignCenter, "验证失败! 请调整棋子位置");
    }
    drawStatusText(painter);
}
void QiPan::drawStatusText(QPainter &painter) {
    painter.setPen(Qt::black);
    painter.setFont(QFont("Arial", 14));
    
    QString statusText;
    switch (m_gameFlowState) {
    case WAITING_PLAYER_VERIFICATION:
        statusText = "等待验证玩家落子...";
        break;
    case WAITING_COMPUTER_VERIFICATION:
        statusText = "等待验证电脑落子...";
        break;
    case COMPUTER_TURN:
        statusText = "电脑思考中...";
        break;
    case PLAYER_TURN:
        statusText = "玩家回合";
        break;
    }
    
    painter.drawText(rect(), Qt::AlignCenter | Qt::AlignBottom, statusText);
}
void QiPan::setVerificationState(int x, int y, ROLE expectedRole) {
    m_verifyX = x;
    m_verifyY = y;
    m_expectedRole = expectedRole;
    
    if (expectedRole == PLAYER) {
        m_gameFlowState = WAITING_PLAYER_VERIFICATION;
    } else {
        m_gameFlowState = WAITING_COMPUTER_VERIFICATION;
    }
    
    update();
}

void QiPan::drawBoard(QPainter &painter) {
    painter.setPen(QPen(Qt::black, 2));
    painter.setBrush(QColor(210, 180, 140));
    painter.drawRoundedRect(m_marginLeft - 10, m_marginTop - 10,
                           BOARD_SIZE * m_cellSize + 20,
                           BOARD_SIZE * m_cellSize + 20,
                           10, 10);
    
    painter.setPen(QPen(Qt::black, 2));
    for (int i = 0; i <= BOARD_SIZE; i++) {
        painter.drawLine(m_marginLeft, m_marginTop + i * m_cellSize,
                        m_marginLeft + BOARD_SIZE * m_cellSize,
                        m_marginTop + i * m_cellSize);
        painter.drawLine(m_marginLeft + i * m_cellSize, m_marginTop,
                        m_marginLeft + i * m_cellSize,
                        m_marginTop + BOARD_SIZE * m_cellSize);
    }
}
void QiPan::drawPieces(QPainter &painter) {
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == EMPTY) continue;

            int centerX = m_marginLeft + x * m_cellSize + m_cellSize / 2;
            int centerY = m_marginTop + y * m_cellSize + m_cellSize / 2;
            int radius = m_cellSize / 3;

            if (m_chessboard[x][y] == PLAYER) {
                if (isPlayerBlack()) {
                    // 玩家棋子：黑色
                    QRadialGradient gradient(centerX, centerY, radius);
                    gradient.setColorAt(0, QColor(80, 80, 80));
                    gradient.setColorAt(1, Qt::black);
                    painter.setBrush(gradient);
                    painter.setPen(Qt::NoPen);
                } else {
                    // 玩家棋子：白色
                    QRadialGradient gradient(centerX, centerY, radius);
                    gradient.setColorAt(0, Qt::white);
                    gradient.setColorAt(1, QColor(200, 200, 200));
                    painter.setBrush(gradient);
                    painter.setPen(QPen(Qt::black, 1));
                }
            } else if (m_chessboard[x][y] == COMPUTER) {
                if (isPlayerBlack()) {
                    // 电脑棋子：白色
                    QRadialGradient gradient(centerX, centerY, radius);
                    gradient.setColorAt(0, Qt::white);
                    gradient.setColorAt(1, QColor(200, 200, 200));
                    painter.setBrush(gradient);
                    painter.setPen(QPen(Qt::black, 1));
                } else {
                    // 电脑棋子：黑色
                    QRadialGradient gradient(centerX, centerY, radius);
                    gradient.setColorAt(0, QColor(80, 80, 80));
                    gradient.setColorAt(1, Qt::black);
                    painter.setBrush(gradient);
                    painter.setPen(Qt::NoPen);
                }
            }
            painter.drawEllipse(QPoint(centerX, centerY), radius, radius);
        }
    }
}



void QiPan::drawHover(QPainter &painter) {
    if (m_gameState != PLAYING || m_currentPlayer != PLAYER) return;
    if (m_hoverX < 0 || m_hoverY < 0 || m_hoverFlag == false) return;
    
    int centerX = m_marginLeft + m_hoverX * m_cellSize + m_cellSize / 2;
    int centerY = m_marginTop + m_hoverY * m_cellSize + m_cellSize / 2;
    int radius = m_cellSize / 3;

    if (isPlayerBlack()) {
        // 玩家悬停效果（黑色半透明）
        painter.setBrush(QColor(0, 0, 0, 60));
    } else {
        // 玩家悬停效果（白色半透明）
        painter.setBrush(QColor(255, 255, 255, 60));
    }
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(QPoint(centerX, centerY), radius, radius);
}

void QiPan::mouseMoveEvent(QMouseEvent *event) {
    if (m_gameState != PLAYING || m_currentPlayer != PLAYER) return;

    int x = (event->x() - m_marginLeft) / m_cellSize;
    int y = (event->y() - m_marginTop) / m_cellSize;

    if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE) {
        if (m_hoverX != x || m_hoverY != y) {
            m_hoverX = x;
            m_hoverY = y;
            m_hoverFlag = true;
            update();
        }
    } else {
        m_hoverX = -1;
        m_hoverY = -1;
        m_hoverFlag = false;
        update();
    }
}

void QiPan::mousePressEvent(QMouseEvent *event) {
    if (m_gameFlowState != PLAYER_TURN) return;

    int x = (event->x() - m_marginLeft) / m_cellSize;
    int y = (event->y() - m_marginTop) / m_cellSize;

    if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE &&
        m_chessboard[x][y] == EMPTY) {
        makeMove(x, y, PLAYER);
        
        // 落子后设置状态为等待验证
        m_gameFlowState = WAITING_PLAYER_VERIFICATION;
    }
}

void QiPan::makeMove(int x, int y, ROLE role) {
    if (m_gameState != PLAYING) 
        return;
    
    // 直接落子，不进行验证
    m_chessboard[x][y] = role;
    m_moveHistory.append(QPoint(x, y));
    m_moveRoles.append(role);
    
    // 发送移动信号
    if (role == PLAYER) {
        emit playerMoved(x, y);
    } else {
        emit computerMoved(x, y);
    }
    
    // 检查游戏状态
    checkGameState(x, y, role);
    
    // 切换到下一个玩家
    m_currentPlayer = (role == PLAYER) ? COMPUTER : PLAYER;
    
    // 如果下一个是电脑，启动AI计时器
    if (m_currentPlayer == COMPUTER) {
        m_aiTimer.start(500);
    }
    
    update();
    emit gameStatusChanged();
}
void QiPan::handleVerificationResult(int x, int y, bool success) {
    if (x != m_verifyX || y != m_verifyY) 
        return;
    
    if (success) {
        // 验证成功
        m_verificationState = VERIFIED;
        
        // 根据当前状态切换回合
        if (m_gameFlowState == WAITING_PLAYER_VERIFICATION) {
            // 玩家落子验证成功，轮到电脑
            m_currentPlayer = COMPUTER;
            m_gameFlowState = COMPUTER_TURN;
            m_aiTimer.start(500); // 启动电脑移动
        } else if (m_gameFlowState == WAITING_COMPUTER_VERIFICATION) {
            // 电脑落子验证成功，轮到玩家
            m_currentPlayer = PLAYER;
            m_gameFlowState = PLAYER_TURN;
        }
    } else {
        // 验证失败
        m_verificationState = FAILED;
        
        if (m_gameFlowState == WAITING_PLAYER_VERIFICATION) {
            // 移除玩家落子
            m_chessboard[x][y] = EMPTY;
            m_gameFlowState = PLAYER_TURN;
            QMessageBox::warning(this, "验证失败", "棋子未被正确放置，请重试！");
        } else if (m_gameFlowState == WAITING_COMPUTER_VERIFICATION) {
            // 电脑落子失败，重新尝试
            m_gameFlowState = COMPUTER_TURN;
            m_aiTimer.start(500); // 重新尝试电脑移动
        }
    }
    
    update();
    emit gameStatusChanged();
}

void QiPan::checkGameState(int x, int y, ROLE role) {
    if (isCheckWin(x, y, role)) {
        m_gameState = (role == PLAYER) ? PLAYER_WIN : COMPUTER_WIN;
        m_winner = role;
        return;
    }

    if (isBoardFull()) {
        m_gameState = DRAW;
        m_winner = EMPTY;
    }
}

bool QiPan::isCheckWin(int x, int y, ROLE role) {
    bool rowWin = true;
    for (int i = 0; i < BOARD_SIZE; i++) {
        if (m_chessboard[x][i] != role) {
            rowWin = false;
            break;
        }
    }
    if (rowWin) return true;

    bool colWin = true;
    for (int i = 0; i < BOARD_SIZE; i++) {
        if (m_chessboard[i][y] != role) {
            colWin = false;
            break;
        }
    }
    if (colWin) return true;

    if (x == y) {
        bool diagWin = true;
        for (int i = 0; i < BOARD_SIZE; i++) {
            if (m_chessboard[i][i] != role) {
                diagWin = false;
                break;
            }
        }
        if (diagWin) return true;
    }

    if (x + y == BOARD_SIZE - 1) {
        bool antiDiagWin = true;
        for (int i = 0; i < BOARD_SIZE; i++) {
            if (m_chessboard[i][BOARD_SIZE - 1 - i] != role) {
                antiDiagWin = false;
                break;
            }
        }
        if (antiDiagWin) return true;
    }

    return false;
}

bool QiPan::isBoardFull() {
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == EMPTY) {
                return false;
            }
        }
    }
    return true;
}

void QiPan::computerMove() {
    if (m_gameFlowState != COMPUTER_TURN) return;

    QPoint move;

    switch (m_aiLevel) {
        case 1:
            move = findRandomMove();
            break;
        case 2:
            move = findWinningMove(COMPUTER);
            if (move.x() == -1) move = findWinningMove(PLAYER);
            if (move.x() == -1) move = findRandomMove();
            break;
        case 3:
            move = findBestMove();
            break;
        default:
            move = findRandomMove();
    }

    if (move.x() != -1 && move.y() != -1) {
        makeMove(move.x(), move.y(), COMPUTER);
        
        // 落子后设置状态为等待验证
        m_gameFlowState = WAITING_COMPUTER_VERIFICATION;
    }
}

QPoint QiPan::findBestMove() {
    int bestVal = -1000;
    QPoint bestMove(-1, -1);

    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == EMPTY) {
                m_chessboard[x][y] = COMPUTER;
                int moveVal = minimax(0, false, -1000, 1000);
                m_chessboard[x][y] = EMPTY;

                if (moveVal > bestVal) {
                    bestMove = QPoint(x, y);
                    bestVal = moveVal;
                }
            }
        }
    }

    return bestMove;
}

QPoint QiPan::findWinningMove(ROLE role) {
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == EMPTY) {
                m_chessboard[x][y] = role;
                bool win = isCheckWin(x, y, role);
                m_chessboard[x][y] = EMPTY;
                if (win) return QPoint(x, y);
            }
        }
    }
    return QPoint(-1, -1);
}

QPoint QiPan::findRandomMove() {
    QList<QPoint> emptyCells;
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == EMPTY) {
                emptyCells.append(QPoint(x, y));
            }
        }
    }

    if (!emptyCells.isEmpty()) {
        int index = QRandomGenerator::global()->bounded(emptyCells.size());
        return emptyCells[index];
    }
    return QPoint(-1, -1);
}

int QiPan::minimax(int depth, bool isMax, int alpha, int beta) {
    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == COMPUTER && isCheckWin(x, y, COMPUTER)) {
                return 10 - depth;
            }
        }
    }

    for (int x = 0; x < BOARD_SIZE; x++) {
        for (int y = 0; y < BOARD_SIZE; y++) {
            if (m_chessboard[x][y] == PLAYER && isCheckWin(x, y, PLAYER)) {
                return depth - 10;
            }
        }
    }

    if (isBoardFull()) {
        return 0;
    }

    if (isMax) {
        int best = -1000;

        for (int x = 0; x < BOARD_SIZE; x++) {
            for (int y = 0; y < BOARD_SIZE; y++) {
                if (m_chessboard[x][y] == EMPTY) {
                    m_chessboard[x][y] = COMPUTER;
                    best = qMax(best, minimax(depth + 1, !isMax, alpha, beta));
                    alpha = qMax(alpha, best);
                    m_chessboard[x][y] = EMPTY;

                    if (beta <= alpha) break;
                }
            }
        }
        return best;
    } else {
        int best = 1000;

        for (int x = 0; x < BOARD_SIZE; x++) {
            for (int y = 0; y < BOARD_SIZE; y++) {
                if (m_chessboard[x][y] == EMPTY) {
                    m_chessboard[x][y] = PLAYER;
                    best = qMin(best, minimax(depth + 1, !isMax, alpha, beta));
                    beta = qMin(beta, best);
                    m_chessboard[x][y] = EMPTY;

                    if (beta <= alpha) break;
                }
            }
        }
        return best;
    }
}

void QiPan::regretMove() {
    if (m_moveHistory.isEmpty() || m_gameState != PLAYING) return;

    QList<QPair<ROLE, QPoint>> removedPieces; // 记录被移除的棋子

    QPoint lastMove = m_moveHistory.takeLast();
    ROLE lastRole = m_moveRoles.takeLast();
    m_chessboard[lastMove.x()][lastMove.y()] = EMPTY;
    removedPieces.append(qMakePair(lastRole, lastMove));

    if (m_currentPlayer == PLAYER && !m_moveHistory.isEmpty()) {
        QPoint prevMove = m_moveHistory.takeLast();
        ROLE prevRole = m_moveRoles.takeLast();
        m_chessboard[prevMove.x()][prevMove.y()] = EMPTY;
        removedPieces.append(qMakePair(prevRole, prevMove));
    }

    // 通知主窗口移动被移除的棋子
    emit piecesRemoved(removedPieces);

    m_currentPlayer = PLAYER;
    update();
    emit gameStatusChanged();
}

bool QiPan::isPositionOccupied(int x, int y) const {
    if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE) {
        return true; // 无效位置视为已占用
    }
    return m_chessboard[x][y] != EMPTY;
}
void QiPan::setCurrentPlayer(ROLE player) {
    m_currentPlayer = player;
    if (m_currentPlayer == COMPUTER) {
        m_gameFlowState = COMPUTER_TURN;
    } else {
        m_gameFlowState = PLAYER_TURN;
    }
    update();
}